<template>
  <el-tree ref="treeRef" node-key="id" :data="props.options" default-expand-all
           @node-click="click" :expand-on-click-node="false" >
    <template #default="{ node, data }">
      <tree-node :node="node" :data="data" :max-level="maxLevel"
                 :append-node="appendNode" :remove-node="removeNode" :modify-node="modifyNode"></tree-node>
    </template>
  </el-tree>
</template>

<script setup>
import {ref, watch} from 'vue';
import TreeNode from './tree-node.vue';
import Layers from '@/lang//layers/index';

/**
 * 可编辑树形结构
 *
 * 我们的树形结构数据，一般都是采用这种方式实现。
 * 编辑树形结构的数据，我们一般不用树形表格，
 *
 * 采用这种方式：左边是一棵树，右边是表单
 */
const props = defineProps({
    // 已有的树形结构数据，组件内部不做格式转换
    options: {type: Array, default: Layers.array},
    // 设置需要展开的节点，默认展开第一个节点
    expandKey: {type: Array, default:  Layers.array},
    // 最大层级限制，避免用户无限扩展树的节点
    maxLevel: {type: Number, default: undefined},
    // 点击事件
    click: {type: Function, default: undefined},
    // 创建 限定Promise函数 return new node
    create: {type: Function, default: undefined},
    // 删除 限定Promise函数 return boolean/false
    remove: {type: Function, default: undefined},
    // 修改
    modify: {type: Function, default: undefined}
})

// Reference
const treeRef = ref();

// 节点数据
const nodes = ref([]);
// 需要展开的节点列表
const expandId = ref([]);

/**
 * 追加节点
 *
 * @param data 父节点数据
 * @param node 父节点对象
 */
const appendNode = (data, node) => {
    if (props.create) {
        props.create(data, node).then(data => {
            treeRef.value.append(data, node);
        }).catch(err => {
            console.error(err);
        });
    }
};

/**
 * 移除节点
 *
 * @param data 父节点数据
 * @param node 父节点对象
 */
const removeNode = (data, node) => {
    if (props.remove) {
        props.remove(data, node).then(() => {
            treeRef.value.remove(data);
        }).catch(err => {
            console.error(err);
        });
    }
};

/**
 * 修改节点
 *
 * @param data 父节点数据
 * @param node 父节点对象
 */
const modifyNode = (data, node) => {
    if (props.modify) {
        props.modify(data, node);
    }
};

/**
 * 设置树形数据
 *
 * @param opts 树形数据
 */
const setOptions = (opts) => {
    nodes.value = opts;

};

watch(() => props.options, (val) => {
    setOptions(val);
}, {immediate: true});

</script>